// dp[i][j] 表示根为i的结点状态是j的最大快乐数
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 6010, INF = 0x3f;
int h[N], e[N], ne[N], idx = 0;
int a[N];
int dp[N][2];
bool flag[N];
int n, root;
// 将b作为a的子节点
void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

// dp[i][1] : 当前员工去参加舞会的最大情况
// dp[i][0] : 当前员工不参加舞会的最大情况
void dfs(int u)
{
    // 如果是叶子结点，那就只有两种情况
    dp[u][0] = 0;
    dp[u][1] = a[u];
    for(int i = h[u]; ~i; i = ne[i])
    {
        int nd = e[i];
        dfs(nd);
        dp[u][0] += max(dp[nd][1], dp[nd][0]);
        dp[u][1] += dp[nd][0];
    }
    // dp[u][0] += max(dp[son][1], dp[son][0])
    // dp[u][1] = a[u] + dp[son][0]; 
}

int main()
{
    memset(h, -1, sizeof h);
    memset(dp, INF, sizeof dp);
    cin >> n;
    for(int i = 1; i <= n; ++i) cin >> a[i];
    for(int i = 1; i < n; ++i)
    {
        int a, b;
        cin >> a >> b;
        add(b, a);
        flag[a] = true;
    }
    // 找到整棵树的根结点
    for(int i = 1; i <= n; ++i)
        if(!flag[i])
        {
            root = i;
            break;
        }
    // 从根节点开始dp
    
    dfs(root);
    cout << max(dp[root][0], dp[root][1]) << endl;
    return 0;
}